package com.ruoyi.pos.service.impl.system;

import com.ruoyi.pos.domain.system.PosGroup;
import com.ruoyi.pos.domain.dto.system.request.GroupQueryRequest;
import com.ruoyi.pos.domain.dto.system.response.GroupResponse;
import com.ruoyi.pos.domain.dto.common.response.BasePageResponse;
import com.ruoyi.pos.mapper.system.PosGroupMapper;
import com.ruoyi.pos.service.system.IPosGroupService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * POS柜组Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-01-30
 */
@Service
@Transactional(transactionManager = "posTransactionManager")
public class PosGroupServiceImpl implements IPosGroupService {

    @Autowired
    private PosGroupMapper posGroupMapper;

    /**
     * 查询单个柜组信息
     * 支持根据ID、编码查询
     * 
     * @param request 查询请求
     * @return 柜组信息
     */
    @Override
    public GroupResponse getGroup(GroupQueryRequest request) {
        PosGroup group = null;
        
        if (request.getGroupId() != null) {
            group = posGroupMapper.selectPosGroupById(request.getGroupId());
        } else if (StringUtils.isNotEmpty(request.getGroupCode())) {
            group = posGroupMapper.selectPosGroupByCode(request.getGroupCode());
        }
        
        if (group == null) {
            return null;
        }
        
        return convertToResponse(group);
    }

    /**
     * 分页查询柜组列表
     * 
     * @param request 查询请求
     * @return 分页响应
     */
    @Override
    public BasePageResponse<GroupResponse> queryGroups(GroupQueryRequest request) {
        PosGroup group = new PosGroup();
        group.setGroupId(request.getGroupId());
        group.setGroupCode(request.getGroupCode());
        group.setGroupName(request.getGroupName());
        group.setGroupType(request.getGroupType());
        group.setStatus(request.getStatus());
        
        List<PosGroup> groups = posGroupMapper.selectPosGroupList(group);
        List<GroupResponse> responses = groups.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
        
        return new BasePageResponse<>(responses, groups.size());
    }

    /**
     * 构建柜组树结构
     * 
     * @return 柜组树结构
     */
    @Override
    public List<GroupResponse> buildGroupTree() {
        List<PosGroup> allGroups = posGroupMapper.selectPosGroupList(new PosGroup());
        List<GroupResponse> responses = allGroups.stream()
                .map(this::convertToResponse)
                .collect(Collectors.toList());
        
        // 构建树形结构
        return buildTree(responses);
    }

    /**
     * 构建树形结构
     * 
     * @param groups 所有柜组
     * @return 树形结构
     */
    private List<GroupResponse> buildTree(List<GroupResponse> groups) {
        // 按父级ID分组
        Map<Long, List<GroupResponse>> groupMap = groups.stream()
                .collect(Collectors.groupingBy(group -> group.getParentId() != null ? group.getParentId() : 0L));
        
        // 获取根节点
        List<GroupResponse> rootGroups = groupMap.getOrDefault(0L, new ArrayList<>());
        
        // 递归构建子节点
        for (GroupResponse rootGroup : rootGroups) {
            buildChildren(rootGroup, groupMap);
        }
        
        return rootGroups;
    }

    /**
     * 递归构建子节点
     * 
     * @param parent 父节点
     * @param groupMap 分组映射
     */
    private void buildChildren(GroupResponse parent, Map<Long, List<GroupResponse>> groupMap) {
        List<GroupResponse> children = groupMap.get(parent.getGroupId());
        if (children != null && !children.isEmpty()) {
            parent.setChildren(children);
            for (GroupResponse child : children) {
                buildChildren(child, groupMap);
            }
        }
    }

    /**
     * 转换实体为响应DTO
     * 
     * @param group 柜组实体
     * @return 柜组响应DTO
     */
    private GroupResponse convertToResponse(PosGroup group) {
        GroupResponse response = new GroupResponse();
        BeanUtils.copyBeanProp(response, group);
        return response;
    }
}
